#ifndef RUMDFILEMODEL_H
#define RUMDFILEMODEL_H

#include <QObject>
#include <QHash>
#include <QByteArray>
#include <QString>
#include "rfilemodel.h"

class RUmdFileModel : public RFileModel
{
    Q_OBJECT
public:
    RUmdFileModel(REngine& engine, QObject *parent = 0);
    ~RUmdFileModel();
    enum UmdTag{
        VERSION = 0x01,
        TITLE = 0x02,
        AUTHOR = 0x03,
        YEAR = 0x04,
        MONTH = 0x05,
        DAY = 0x06,
        GENDER = 0x07,
        PUBLISHER = 0x08,
        VENDOR = 0x09,
        CONTENT_LENGTH = 0x0B,
        FIXED_LEN = 0x0C,
        REF_CONTENT = 0x81,
        COVER_PAGE = 0x82,
        CHAP_OFF = 0x83,
        CHAP_STR = 0x84,
        PAGE_OFFSET = 0x87,
        CONTENT_ID = 0x0A,
        CDS_KEY = 0xF0,
        LICENSE_KEY = 0xF1
    };

    enum UmdKey {
        FUNCTION_KEY = 0x23,
        DATA_KEY = 0x24
    };

    enum UmdVersion {
        TEXT = 0x1,
        COMIC = 0X2
    };
    static const quint32 KUmdFileKey = 0xDE9A9B89;
    static const quint32 KUmdFileKeyLen = 4;
    static const quint32 KUmdKeyLen = 1;

    //****************Start Data definition****************************
    static const quint32 KUmdDataValueLen = 4;
    static const quint32 KUmdDataLengthLen = 4;
    //Head length, not include key
    static const quint32 KUmdDataHeadLen = KUmdDataValueLen + KUmdDataLengthLen;
    //Head total length, include key
    static const quint32 KUmdDataHeadFullLen = KUmdKeyLen + KUmdDataHeadLen;

    //Chapter offset
    static const quint32 KUmdDataChapterOffLen = 4;

    //Chapter
    static const quint32 KUmdDataChapterLengthLen = 1;

    //Content
    static const quint32 KUmdDataContentValueLen = KUmdDataValueLen;
    //****************End Data definition******************************


    //****************Start Function definition************************
    static const quint32 KUmdFuncCategoryLen = 2;
    static const quint32 KUmdFuncUnkownLen = 1;
    static const quint32 KUmdFuncLengthLen = 1;
    //Head length, not include key
    static const quint32 KUmdFuncHeadLen = KUmdFuncCategoryLen + KUmdFuncUnkownLen + KUmdFuncLengthLen;
    //Head total length, include key
    static const quint32 KUmdFuncHeadFullLen = KUmdKeyLen + KUmdFuncHeadLen;

    //Content reference
    static const quint32 KUmdContentValueLen = 4;
    static const quint32 KUmdContentTotalLen = KUmdContentValueLen;

    //Chapter offset
    static const quint32 KUmdChapterOffValueLen = 4;
    static const quint32 KUmdChapterOffTotalLen = KUmdChapterOffValueLen;

    //Chapter string
    static const quint32 KUmdChapterValueLen = 4;
    static const quint32 KUmdChapterTotalLen = KUmdChapterValueLen;

    //Cover
    static const quint32 KUmdCoverTypeLen = 1;
    static const quint32 KUmdCoverValueLen = 4;
    static const quint32 KUmdCoverTotalLen = KUmdCoverTypeLen + KUmdCoverValueLen;
    //***************End Function definition*********************

public://From RFileModel
    int lineNumberOfChapter(int chapterIndex);
    int currentChapterIndex();
    void chapters(QStringList& chapterList);

protected://From RFileModel
    bool analyzeFile();
    bool openFile(const QString& fileName);
    bool saveFileLinePosition();
    bool readFileLinePosition();
    bool initFileInfo();
    QVariant data(int row) const;

private:
    bool processData();
    bool processFunction();
    bool processContent();
    bool processChapterOffset();
    bool processChapterString();
    QByteArray uncompressContent(QByteArray& content);
    bool storeUncompressedContent(QByteArray &content);
    bool openFile(const QString& fileName, QFile *& file, QIODevice::OpenMode mode);
    bool analyzeUncompressedFile();

private:
    int m_version;
    QString m_title;
    QString m_author;
    QString m_year;
    QString m_month;
    QString m_day;
    QString m_gender;
    QString m_publisher;
    QString m_vendor;
    quint32 m_file_length;
    quint32 m_fixed_len;
    quint32 m_chapter_offset_value;
    quint32 m_chapter_value;
    quint32 m_cover_type;
    quint32 m_cover_value;
    quint32 m_content_value;
    QHash<quint32, QByteArray> m_data;
    QList<quint32> m_file_chapter_offset;
    QFile *m_uncompressed_file;
    bool m_file_analyzed;
};

#endif // RUMDFILEMODEL_H
